/*
 * AD9954 Register function driver source file
 */

#include <stdint.h>
#include <stdbool.h>
#include "hw_ad9954.h"
#include "ad9954.h"

void ad9954_init(void)
{
	ad9954_io_init();
	ad9954_hwrst();
}

void ad9954_rst(void)
{
	ad9954_hwrst();
}

uint32_t ad9954_set_clk(uint32_t refclk, uint32_t mul)
{
	uint32_t clk;
	uint32_t tmp;
	uint8_t cache[3];
    
	refclk=refclk>25000000?25000000:refclk;
	mul=mul>0x0000001f?0x0000001f:mul;
    clk=refclk*mul;

	if(clk>250000000)
		tmp=(mul<<3)|VCO_RANGE;
	else
		tmp=mul<<3;

	//tmp |= (XTAL_OUT_EN | CHG_PUMP_BIT1 | CHG_PUMP_BIT0);

	cache[0]=(tmp>>16)&0xff;
	cache[1]=(tmp>>8)&0xff;
	cache[2]=tmp&0xff;

	ad9954_cfr2_write(cache);
	ad9954_update();
	//ad9954_iosync();

	return clk;
}

void ad9954_single_tone(uint32_t freq, uint32_t phase, uint32_t clk)
{
    // 1<<32 is too large, so him use 0xffffffff
	uint32_t fword=(uint32_t)((double)(0xffffffff)/(double)clk*(double)freq);
	uint32_t pword=(uint32_t)((double)(1<<14)/(double)360*(double)phase);
	uint8_t cache[4];

	uint32_t cfr1=AUTO_CLR_PHASE_ACC | AUTO_CLR_FREQ_ACC;

	cache[0]=(cfr1>>24)&0xff;
	cache[1]=(cfr1>>16)&0xff;
	cache[2]=(cfr1>>8)&0xff;
	cache[3]=cfr1&0xff;
	ad9954_cfr1_write(cache);

	cache[0]=(fword>>24)&0xff;
	cache[1]=(fword>>16)&0xff;
	cache[2]=(fword>>8)&0xff;
	cache[3]=fword&0xff;
	ad9954_ftw0_write(cache);

	cache[0]=(pword>>8)&0x3f;
	cache[1]=pword&0xff;
	ad9954_pow0_write(cache);

	ad9954_update();
}
